﻿/*
 * Created by SharpDevelop.
 * User: ratul
 * Date: 3/3/2010
 * Time: 3:06 PM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;

namespace H264Impl.NET
{
	/// <summary>
	/// Description of BitStream.
	/// </summary>
	public class BitStream
	{
		public BitStream(byte[] data)
		{
			this.data = data;
			byteReadPtr = 0;
			bitReadPointer = 0;
			length = (UInt32)(data.Length) * 8;
			
			byteWritePtr = (UInt32)(data.Length + 1);
			bitWritePointer = 0;
		}
		
		public BitStream(UInt16 size)
		{
			data = new byte[size];
			byteReadPtr = 65555;
			bitReadPointer = 255;
			length = (UInt32)(data.Length) * 8;
		}
		
		byte[] data;
		UInt32 length;
		
		UInt32 byteReadPtr;
		byte bitReadPointer;
		
		UInt32 byteWritePtr;
		byte bitWritePointer;
		
		public void addBit(bool val)
		{
			//data[byteReadPtr];
			
		}
		
		public bool getBit()
		{
			if(data.Length == byteReadPtr) 
					throw new StreamException("End Of Stream reached");
			
			int result = ((data[byteReadPtr])<<(24 + bitReadPointer++))>> 31;
			length--;
			
			if(bitReadPointer == 8)
			{
				bitReadPointer = 0;
				byteReadPtr++;
			//	if(data.Length == bytePtr) 
			//		throw new StreamException("End Of Stream reached");
			}
			if(result == 0)
				return false;
			else
				return true;
			
			
		}
		
		public bool peekBit()
		{
			return false;
		}
		
		public bool peekBits()
		{
			return false;
		}
		
		public UInt32 getBits(UInt16 noOfBits)
		{
			UInt32 result = 0;
			UInt32 temp;
			if(noOfBits>32)
				throw new ArgumentOutOfRangeException();
			while(noOfBits>0)
			{
				temp = 0;
				try
				{
					bool b = getBit();
	
					if(b == true)
						temp = 1;
					else
						temp = 0;
					result = result | temp<<(noOfBits-1);
					noOfBits--;
				}
				catch (StreamException e)
				{
					throw e;
				}
			}
			
			return result;
		}
	}
}
